package top.ligongzi.hrm.service.impl;

import top.ligongzi.hrm.constants.VerificationConstant;
import top.ligongzi.hrm.domain.VipUser;
import top.ligongzi.hrm.exception.GlobalException;
import top.ligongzi.hrm.exception.ValidUtils;
import top.ligongzi.hrm.mapper.VipUserMapper;
import top.ligongzi.hrm.service.IVerifyCodeService;
import top.ligongzi.hrm.service.IVipUserService;
import top.ligongzi.hrm.util.StrUtils;
import top.ligongzi.hrm.util.VerifyCodeUtils;
import top.ligongzi.hrm.vo.ImgCodeVo;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Lists;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private VipUserMapper vipUserMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public String getImgCode(String key) {
        //产生验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //存放redis
        redisTemplate.opsForValue().set(key, code,
                5, TimeUnit.MINUTES);

        //合并到图片
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try {
            VerifyCodeUtils.outputImage(140, 40, data, code);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //加密
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data.toByteArray());
    }

    @Override
    public void sendSmsCode(ImgCodeVo imgCodeVo) {
        //检验手机号
        ValidUtils.assertNotNull(imgCodeVo.getMobile(), "请输入手机号！");
        ValidUtils.assertNotNull(imgCodeVo.getImageCodeKey(), "请通过合法手段访问！！");
        ValidUtils.assertNotNull(imgCodeVo.getImageCode(), "请输入图片验证码！");
        //不能重复注册
        List<VipUser> vipUsers = vipUserMapper
                .selectList(new EntityWrapper<VipUser>().eq("phone", imgCodeVo.getMobile()));
        ValidUtils.assertListNull(vipUsers, "用户已存在，不能重复注册");
        //校验图片验证码
        Object obj = redisTemplate.opsForValue().get(imgCodeVo.getImageCodeKey());
        ValidUtils.assertNotNull(obj, "验证码以过期，请重新刷新页面！");
        String imgCodeFromRedis = (String) obj;
        ValidUtils.assertEqualIgnoreCase(imgCodeVo.getImageCode(), imgCodeFromRedis, "请输入正确图片验证码"); //不区分大小写比对
        //法短信验证码
        String key = VerificationConstant.USER_REG + ":" + imgCodeVo.getMobile();
        sendMobileRegCode(key,imgCodeVo.getMobile());
    }

    /**
     * 产生的验证码有效期是5分钟，如果在1分钟以内点击了多次按钮，就提示用户，一分钟以内不能发送多次验证码，如果超过了1分钟，但在
     * 5分钟以内，依然使用第一次产生的验证码，如果超过了5分钟就发送全新的验证码
     * @param phone
     * @param key  redis的key值（验证码对应的key值）
     */
    public void sendMobileRegCode(String key,String phone)  {
        //产生随机验证码
        String code = StrUtils.getComplexRandomString(4);
        //通过key值，在redis中查找验证码是否存在
        String codeValue = (String) redisTemplate.opsForValue().get(key);
        //如果codeValue存在，就证明验证码还没有过期
        if(!StringUtils.isEmpty(codeValue)){
            String beginTimer = codeValue.split(":")[1];
            //结束毫秒时间-开始毫秒时间
            if((System.currentTimeMillis()-Long.valueOf(beginTimer))<60*1000){

                throw new GlobalException("一分钟以内不能发送多次验证码!!");
            }
            //超过了1分钟，但依然在5分钟以内
            code = codeValue.split(":")[0];
        }
        //产生的验证码放到redis里面
        redisTemplate.opsForValue().set(key, code+":"+System.currentTimeMillis(),
                5, TimeUnit.MINUTES);
        String content = "尊敬的来宾,您的验证码为:" + code + ",请在5分钟以内完成验证操作!!";
        System.out.println(content);
        //发送短信
//        SendMsgUtil.sendMsg(phone, content);

    }
}
